/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: DcmDspSvc31.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: Dcm
*
*******************************************************************************/

/** HEADER FILES **/
#include "DcmDspSvc31.h"
#include "DcmDsp.h"


/** MACRO DEFINITION **/
#define DCM_PROGRESS_ROUTINEID_CHECK ((Dcm_ProgressType)0x10u)
#define DCM_PROGRESS_START_ROUTINE ((Dcm_ProgressType)0x11u)
#define DCM_PROGRESS_STOP_ROUTINE ((Dcm_ProgressType)0x12u)
#define DCM_PROGRESS_REQUEST_ROUTINE_RESULT ((Dcm_ProgressType)0x13u)

/* The following index refer to Dcm_MsgContextType reqData and resData, start after service identifier(which is not part
of this data) */
#define DCM_REQ_DATA_ROUTINE_CONTROL_TYPE_INDEX  0u
#define DCM_REQ_DATA_ROUTINE_ID_HIGH_INDEX        1u
#define DCM_REQ_DATA_ROUTINE_ID_LOW_INDEX         2u
#define DCM_REQ_DATA_ROUTINE_CONTROL_OPTION_RECORD_SRART 3u

#define DCM_RES_DATA_ROUTINE_CONTROL_TYPE_INDEX  0u
#define DCM_RES_DATA_ROUTINE_ID_HIGH_INDEX        1u
#define DCM_RES_DATA_ROUTINE_ID_LOW_INDEX         2u
#define DCM_RES_DATA_ROUTINE_STATUS_RECORD_SRART  3u

#define DCM_START_ROUTINE  0x01
#define DCM_STOP_ROUTINE   0x02
#define DCM_REQUEST_ROUTINE_RESULT   0x03

/** TYPEDEF DEFINITION **/


/** LOCAL DATA DECLARATION **/


/** GLOBAL DATA DECLARATION **/


/** LOCAL FUNCTION DECLARATION **/


/** GLOBAL FUNCTION DECLARATION **/


/** LOCAL DATA **/


/** GLOBAL DATA **/


/** LOCAL FUNCTION **/


/** GLOBAL FUNCTION **/

/*******************************************************************************
* -Name            DcmDsp_Svc31_Processor
* -Brief           Processor for RoutineControl (31 hex) sub service 
* -Details         None
* -Param[in]       OpStatus: The operations status        
* -Param[in, out]  pMsgContext: Message context 
* -Param[out]      ErrorCode: Negative response code
* -Return          E_OK:          
*                  E_NOT_OK: 
*******************************************************************************/
Std_ReturnType DcmDsp_Svc31_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
)
{
    Std_ReturnType retVal = E_NOT_OK;
    uint16 routineId;
    static uint16 routineIdIndex;
    DcmDspRoutineType* dcmDspRoutineCfgPtr;
    uint8 routineControlType;
    uint16 variableDataLength = 0u;
    uint8 dataIndexTemp = 0u;
    uint8 signalIndex = 0u;

    switch(Dcm_GetProgress(pMsgContext))
    {
        case DCM_PROGRESS_INITIAL:
        {
            retVal = DCM_E_PENDING;
            Dcm_SetProgress(pMsgContext, DCM_PROGRESS_ROUTINEID_CHECK);
            break;
        }
        case DCM_PROGRESS_ROUTINEID_CHECK:
        {
            routineControlType = pMsgContext->reqData[DCM_REQ_DATA_ROUTINE_CONTROL_TYPE_INDEX];
            routineId = (uint16)(((uint16)pMsgContext->reqData[DCM_REQ_DATA_ROUTINE_ID_HIGH_INDEX] << 8) + pMsgContext->reqData[DCM_REQ_DATA_ROUTINE_ID_LOW_INDEX]); 
            *ErrorCode = DCM_E_REQUESTOUTOFRANGE;
            for(routineIdIndex = 0u; routineIdIndex < DcmDspSvc31Conf_RoutineId_Max; routineIdIndex++)
            {
                dcmDspRoutineCfgPtr = (DcmDspRoutineType*)(&DcmDspRoutine[routineIdIndex]);
                if(routineId == dcmDspRoutineCfgPtr->DcmDspRoutineIdentifier)
                {
                    if(DCM_START_ROUTINE == routineControlType)
                    {
                        Dcm_SetProgress(pMsgContext, DCM_PROGRESS_START_ROUTINE);
                        retVal = DCM_E_PENDING;
                    }
                    else if(DCM_STOP_ROUTINE == routineControlType)
                    {
                        Dcm_SetProgress(pMsgContext, DCM_PROGRESS_STOP_ROUTINE);
                        retVal = DCM_E_PENDING;
                    }
                    else if(DCM_REQUEST_ROUTINE_RESULT == routineControlType)
                    {
                        Dcm_SetProgress(pMsgContext, DCM_PROGRESS_REQUEST_ROUTINE_RESULT);
                        retVal = DCM_E_PENDING;
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    
                    break;
                }
            }
            break;
        }
        case DCM_PROGRESS_START_ROUTINE:
        {
            dcmDspRoutineCfgPtr = (DcmDspRoutineType*)(&DcmDspRoutine[routineIdIndex]);
            if(NULL_PTR != dcmDspRoutineCfgPtr->DcmDspStartRoutine.DcmDspStartRoutineFnc)
            {
                retVal = dcmDspRoutineCfgPtr->DcmDspStartRoutine.DcmDspStartRoutineFnc(OpStatus,
                                                                                       (uint8*)(&pMsgContext->reqData[DCM_REQ_DATA_ROUTINE_CONTROL_OPTION_RECORD_SRART]),
                                                                                       (uint8*)(&pMsgContext->resData[DCM_RES_DATA_ROUTINE_STATUS_RECORD_SRART]),
                                                                                       (uint16*)&variableDataLength,
                                                                                       ErrorCode);
                pMsgContext->resDataLen = 3u;
                for(signalIndex = 0u; signalIndex < dcmDspRoutineCfgPtr->DcmDspStartRoutine.DcmDspStartRoutineOut.DcmDspStartRoutineOutSignalNum; signalIndex++)
                {
                    pMsgContext->resDataLen = pMsgContext->resDataLen + dcmDspRoutineCfgPtr->DcmDspStartRoutine.DcmDspStartRoutineOut.DcmDspStartRoutineOutSignal->DcmDspRoutineParameterSize;
                }
            }

            break;
        }
        case DCM_PROGRESS_STOP_ROUTINE:
        {
            dcmDspRoutineCfgPtr = (DcmDspRoutineType*)(&DcmDspRoutine[routineIdIndex]);
            if(NULL_PTR != dcmDspRoutineCfgPtr->DcmDspStopRoutine.DcmDspStopRoutineFnc)
            {
                retVal = dcmDspRoutineCfgPtr->DcmDspStopRoutine.DcmDspStopRoutineFnc(OpStatus,
                                                                                    (uint8*)(&pMsgContext->reqData[DCM_REQ_DATA_ROUTINE_CONTROL_OPTION_RECORD_SRART]),
                                                                                    (uint8*)(&pMsgContext->resData[DCM_RES_DATA_ROUTINE_STATUS_RECORD_SRART]),
                                                                                    (uint16*)&variableDataLength,
                                                                                    ErrorCode);
                pMsgContext->resDataLen = 3u;
                for(signalIndex = 0u; signalIndex < dcmDspRoutineCfgPtr->DcmDspStopRoutine.DcmDspStopRoutineOut.DcmDspStopRoutineOutSignalNum; signalIndex++)
                {
                    pMsgContext->resDataLen = pMsgContext->resDataLen + dcmDspRoutineCfgPtr->DcmDspStopRoutine.DcmDspStopRoutineOut.DcmDspStopRoutineOutSignal->DcmDspRoutineParameterSize;
                }
            }

            break;
        }
        case DCM_PROGRESS_REQUEST_ROUTINE_RESULT:
        {
            dcmDspRoutineCfgPtr = (DcmDspRoutineType*)(&DcmDspRoutine[routineIdIndex]);
            if(NULL_PTR != dcmDspRoutineCfgPtr->DcmDspRequestRoutineResults.DcmDspRequestRoutineResultsFnc)
            {
                retVal = dcmDspRoutineCfgPtr->DcmDspRequestRoutineResults.DcmDspRequestRoutineResultsFnc(OpStatus,
                                                                                                        (uint8*)(&pMsgContext->reqData[DCM_REQ_DATA_ROUTINE_CONTROL_OPTION_RECORD_SRART]),
                                                                                                        (uint8*)(&pMsgContext->resData[DCM_RES_DATA_ROUTINE_STATUS_RECORD_SRART]),
                                                                                                        (uint16*)&variableDataLength,
                                                                                                        ErrorCode);
                pMsgContext->resDataLen = 3u;
                for(signalIndex = 0u; signalIndex < dcmDspRoutineCfgPtr->DcmDspRequestRoutineResults.DcmDspRequestRoutineResultsOut.DcmDspRequestRoutineResultsOutSignalNum; signalIndex++)
                {
                    pMsgContext->resDataLen = pMsgContext->resDataLen + dcmDspRoutineCfgPtr->DcmDspRequestRoutineResults.DcmDspRequestRoutineResultsOut.DcmDspRequestRoutineResultsOutSignal->DcmDspRoutineParameterSize;
                }
            }

            break;
        }
        default:
        {
            *ErrorCode = DCM_E_REQUESTOUTOFRANGE;
            break;
        }
    }

    return(retVal);
}


